﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Appkiz.Apps.Workflow.Library;
using Appkiz.Library.Notification;
using Appkiz.Library.Security;
using System.Xml;
using Tiger.Models;
using Jiguang.JPush;
using Jiguang.JPush.Model;
using Appkiz.Apps.Calendar.Models.Data;

namespace Tiger.Common
{
    public class WorkflowUtil
    {
        // 通知管理
        private static NotificationMgr notifyMgr = new NotificationMgr();
        // 流程管理
        private static WorkflowMgr wkfMgr = new WorkflowMgr();
        // 用户管理
        private static OrgMgr orgMgr = new OrgMgr();

        /// <summary>
        /// 发送通知
        /// </summary>
        /// <param name="MessageID">消息ID</param>
        /// <param name="TargetEmployeeID">接收人ID</param>
        public static bool SendNotification(string MessageID, string NodeKey, string TargetEmployeeID)
        {
            // 根据消息ID获得对应的标题
            Appkiz.Apps.Workflow.Library.Message message = wkfMgr.GetMessage(MessageID);
            if (message == null)
            {
                return false;
            }
            else
            {
                var data = Newtonsoft.Json.JsonConvert.SerializeObject(new
                {
                    MessageID = MessageID,
                    NodeKey = NodeKey,
                    NewWin = true,
                    Url = "/Apps/Workflow/Running/Open?mid=" + MessageID + "&nid=" + NodeKey
                });
                notifyMgr.SendNotification("Workflow", TargetEmployeeID, string.Format("您有新的流程处理通知 \"{0}\"", message.MessageTitle), data);
                return true;
            }
        }

        /// <summary>
        /// 发送通知
        /// </summary>
        /// <param name="MessageID">消息ID</param>
        /// <param name="TargetEmployeeID">接收人ID</param>
        public static bool SendLeaderNotification(string MessageID, string NodeKey, string TargetEmployeeID)
        {
            // 根据消息ID获得对应的标题
            Appkiz.Apps.Workflow.Library.Message message = wkfMgr.GetMessage(MessageID);
            if (message == null)
            {
                return false;
            }
            else
            {
                var data = Newtonsoft.Json.JsonConvert.SerializeObject(new
                {
                    MessageID = MessageID,
                    NodeKey = NodeKey,
                    NewWin = true,
                    Url = "/Apps/Workflow/Running/Open?mid=" + MessageID + "&nid=" + NodeKey
                });
                notifyMgr.SendNotification("Workflow", TargetEmployeeID, string.Format("您有新的领导批示通知 \"{0}\"", message.MessageTitle), data);
                return true;
            }
        }

        /// <summary>
        /// 判断是否可以发送消息（文电科转发节点）
        /// </summary>
        /// <param name="MessageID"></param>
        /// <param name="NodeKey"></param>
        /// <returns></returns>
        public static bool CanSendNotification(string MessageID, string NodeKey)
        {
            // 获取消息
            Appkiz.Apps.Workflow.Library.Message message = wkfMgr.GetMessage(MessageID);
            if (message == null)
            {
                return false;
            }
            else
            {
                // 提醒权限
                bool hasNotifyPermission = false;

                // 获取模板ID
                var templateID = message.FromTemplate;
                if (templateID == WHConstants.Workflow_Read_MessageID &&
                    NodeKey == WHConstants.Workflow_Read_Forward_Node)
                {
                    hasNotifyPermission = true;
                }
                else if (templateID == WHConstants.Workflow_XiaJi_MessageID &&
                  NodeKey == WHConstants.Workflow_XiaJi_Forward_Node)
                {
                    hasNotifyPermission = true;
                }
                else if (templateID == WHConstants.Workflow_ShangJi_MessageID &&
                  NodeKey == WHConstants.Workflow_ShangJi_Forward_Node)
                {
                    hasNotifyPermission = true;
                }
                else
                {
                    hasNotifyPermission = false;
                }

                return hasNotifyPermission;
            }
        }

        /// <summary>
        /// 获得对应流程的相应节点信息
        /// </summary>
        /// <param name="MessageID"></param>
        /// <returns></returns>
        public static Dictionary<string, string> GetWorkflowNode(string MessageID)
        {
            Dictionary<string, string> dict = new Dictionary<string, string>();
            // 获取消息
            Appkiz.Apps.Workflow.Library.Message message = wkfMgr.GetMessage(MessageID);
            if (message == null)
            {
                return null;
            }
            else
            {
                // 获取模板ID
                var templateID = message.FromTemplate;
                if (templateID == WHConstants.Workflow_Read_MessageID)
                {
                    dict["niban"] = WHConstants.Workflow_Read_Niban_Node;
                    dict["forward"] = WHConstants.Workflow_Read_Forward_Node;
                    dict["leader"] = WHConstants.Workflow_Read_Leader_Node;
                    dict["dept"] = WHConstants.Workflow_Read_Dept_Node;
                }
                else if (templateID == WHConstants.Workflow_XiaJi_MessageID)
                {
                    dict["niban"] = WHConstants.Workflow_XiaJi_Niban_Node;
                    dict["forward"] = WHConstants.Workflow_XiaJi_Forward_Node;
                    dict["leader"] = WHConstants.Workflow_XiaJi_Leader_Node;
                    dict["dept"] = WHConstants.Workflow_XiaJi_Dept_Node;
                }
                else if (templateID == WHConstants.Workflow_ShangJi_MessageID)
                {
                    dict["niban"] = WHConstants.Workflow_ShangJi_Niban_Node;
                    dict["forward"] = WHConstants.Workflow_ShangJi_Forward_Node;
                    dict["leader"] = WHConstants.Workflow_ShangJi_Leader_Node;
                    dict["dept"] = WHConstants.Workflow_ShangJi_Dept_Node;
                }
                else
                {
                    // 暂不支持该流程类型
                    dict = null;
                }
                return dict;
            }
        }

        /// <summary>
        /// 返回某用户对应处理节点记录
        /// </summary>
        /// <param name="MessageID"></param>
        /// <param name="EmplID"></param>
        /// <returns></returns>
        public static List<string> GetWorkflowHistory(string MessageID, string EmplID)
        {
            // 历史节点信息
            List<string> nodeKeyList = new List<string>();

            // 获取用户
            Employee employee = orgMgr.GetEmployee(EmplID);

            // 获取消息
            Appkiz.Apps.Workflow.Library.Message message = wkfMgr.GetMessage(MessageID);
            if (message == null)
            {
                return nodeKeyList;
            }
            else
            {
                List<WorkflowHistory> workflowHistoryList = message.History;
                foreach (WorkflowHistory history in workflowHistoryList)
                {
                    // 判断是否是当前用户的节点
                    if (history.HandledBy == employee.EmplID)
                    {
                        nodeKeyList.Add(history.NodeKey);
                    }
                }
                return nodeKeyList;
            }
        }

        /// <summary>
        /// 检查是否能够修改意见
        /// </summary>
        /// <param name="MessageID"></param>
        /// <param name="employee"></param>
        /// <returns></returns>
        public static bool CanChangeOpinion(string MessageID, Employee employee)
        {
            // 获取消息
            Appkiz.Apps.Workflow.Library.Message message = wkfMgr.GetMessage(MessageID);
            if (message == null)
            {
                return false;
            }
            else
            {
                // 判断是否结束
                if (message.MessageStatus == 2)
                {
                    return false;
                }
                else
                {
                    /*
                     * 判断历史记录中该用户是否曾作为领导节点修改过
                     */
                    List<string> HistoryNodes = GetWorkflowHistory(MessageID, employee.EmplID);
                    // 获得对应的节点信息
                    Dictionary<string, string> NodeDict = GetWorkflowNode(MessageID);
                    // 领导节点
                    var LeaderNodeKey = NodeDict["leader"];
                    if (HistoryNodes.Contains(LeaderNodeKey))
                    {
                        string filter1 = "MessageID=@mid and UserID=@user";
                        Dictionary<string, object> paramList1 = new Dictionary<string, object>();
                        paramList1.Add("@mid", (object)MessageID);
                        paramList1.Add("@user", (object)employee.EmplID);
                        string sort1 = "";
                        if (wkfMgr.FindMessageHandle(filter1, paramList1, sort1).Count<MessageHandle>() == 0)
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
            }
        }


        /// <summary>
        /// 获得领导最新意见
        /// </summary>
        /// <param name="MessageID"></param>
        /// <param name="employee"></param>
        /// <returns></returns>
        public static Dictionary<string, string> GetLatestOpinion(string MessageID, string NodeKey, Employee employee)
        {
            /*
             * 变量定义
             */
            // 数据库上下文
            WhDbContext whdb = new WhDbContext();
            // 历史意见
            var resultOpinion = string.Empty;
            // 排序
            var order = string.Empty;
            // 返回结果
            Dictionary<string, string> resultDict = new Dictionary<string, string>();

            // 获取消息
            Doc doc = wkfMgr.GetDocByWorksheetID(wkfMgr.GetDocHelperIdByMessageId(MessageID));
            Worksheet worksheet = doc.Worksheet;
            Workcell workcell = worksheet.GetWorkcell(10, 4);
            XmlNodeList history = workcell.History;

            /*
             * 统计当前用户的原本签批
             */
            // 查找是否有对应的新意见，使用新意见替换旧意见
            int count = 0;

            foreach (XmlNode node in history)
            {
                // 历史意见
                var emplId = node.Attributes.GetNamedItem("emplId").InnerText;


                if (emplId == employee.EmplID)
                {
                    resultOpinion = node.Attributes.GetNamedItem("Value").InnerText;
                    count = count + 1;
                }
            }
            // 如果存在对应修改意见，则替换未修改过的意见
            var newOpinion = whdb.NewOpinion.Where(n => n.MessageID == MessageID && n.NodeKey == NodeKey && n.order == count && n.EmplID == employee.EmplID).FirstOrDefault();
            if (newOpinion != null)
            {
                resultOpinion = newOpinion.Opinion;
                order = Convert.ToString(newOpinion.order);
            }

            resultDict.Add("opinion", resultOpinion);
            resultDict.Add("order", order);

            return resultDict;

        }

        /// <summary>
        /// 获得部门承办最新意见
        /// </summary>
        /// <param name="MessageID"></param>
        /// <param name="NodeKey"></param>
        /// <param name="employee"></param>
        /// <returns></returns>
        public static Dictionary<string, string> GetDeptLatestOpinion(string MessageID, string NodeKey, Employee employee)
        {
            /*
             * 变量定义
             */
            // 数据库上下文
            WhDbContext whdb = new WhDbContext();
            // 历史意见
            var resultOpinion = string.Empty;
            // 排序
            var order = string.Empty;
            // 返回结果
            Dictionary<string, string> resultDict = new Dictionary<string, string>();

            // 获取消息
            Doc doc = wkfMgr.GetDocByWorksheetID(wkfMgr.GetDocHelperIdByMessageId(MessageID));
            Worksheet worksheet = doc.Worksheet;
            Workcell workcell = worksheet.GetWorkcell(12, 4);
            XmlNodeList history = workcell.History;

            /*
             * 统计当前用户的原本签批
             */
            // 查找是否有对应的新意见，使用新意见替换旧意见
            int count = 0;

            foreach (XmlNode node in history)
            {
                // 历史意见
                var emplId = node.Attributes.GetNamedItem("emplId").InnerText;


                if (emplId == employee.EmplID)
                {
                    resultOpinion = node.Attributes.GetNamedItem("Value").InnerText;
                    count = count + 1;
                }
            }

            resultDict.Add("opinion", resultOpinion);
            resultDict.Add("order", order);

            return resultDict;
        }

        #region 获得需通知的文电领导
        public static List<string> GetWendianLeaderList(string mid, string nid, string currentEmplID)
        {
            /*
             * 需通知的用户列表
             */
            var NotifyResultList = new List<string>();

            // 获得【文电领导】组成员
            string WendianLeaderGroup = System.Configuration.ConfigurationManager.AppSettings["WendianLeaderGroup"];

            var sql = @"SELECT 
	                        a.EmplID
                        FROM 
	                        ORG_EmplRole a 
                        INNER JOIN 
	                        ORG_Role b 
                        ON 
	                        a.RoleID = b.RoleID 
                        AND 
	                        b.RoleName = '{0}'";
            var QueryResultList = DbUtil.ExcuteSqlCommand(string.Format(sql, WendianLeaderGroup), DbUtil.ORG_RoleEmplList);

            // 获得该公文部门节点处理人列表
            List<WorkflowHistory> workflowHistoryList = wkfMgr.FindWorkflowHistory(mid, nid);
            var handledList = new List<string>();
            foreach(var history in workflowHistoryList)
            {
                // 过滤当前用户
                if (history.HandledBy != currentEmplID)
                {
                    handledList.Add(history.HandledBy);
                }
            }

            // 取处理记录和文电领导角色的交集
            NotifyResultList = QueryResultList.Select(n => n.ToString()).Intersect(handledList).ToList();

            return NotifyResultList;
        }
        #endregion

        #region 极光推送
        /// <summary>
        /// 极光推送
        /// </summary>
        /// <param name="targets">推送对象数组</param>
        /// <param name="mid">推送数据
        /// {"message":xxx}
        /// </param>
        public static void SendJPushNotification(List<object> targets, Dictionary<string, object> data)
        {
            /*
             * 推送数据解析
             */
            // 消息标题
            var Title = data["title"];
            // 消息类型
            var Type = data["type"];
            // 消息内容
            var content = data["content"];

            // 极光推送AppKey与MasterSecrect获取
            string JPushAppKey = System.Configuration.ConfigurationManager.AppSettings["JPushAppKey"];
            string JPushSecrect = System.Configuration.ConfigurationManager.AppSettings["JPushSecrect"];
            JPushClient PushClient = new JPushClient(JPushAppKey, JPushSecrect);
            PushPayload PayLoad = new PushPayload();
            PayLoad.Platform = "all";
            PayLoad.Audience = new Dictionary<string, object>()
            {
                {"alias", targets }
            };
            PayLoad.Notification = new Notification()
            {
                Alert = data["title"].ToString(),
                Android = new Android()
                {
                    Extras = new Dictionary<string, object>()
                    {
                        {"type", Type },
                        {"content", content }
                    }
                },
                IOS = new IOS
                {
                    Badge = "+1",
                    Extras = new Dictionary<string, object>()
                    {
                        {"type", Type },
                        {"content", content }
                    }
                }
            };
            PayLoad.Options = new Options
            {
                IsApnsProduction = true // 设置 iOS 推送生产环境。不设置默认为开发环境。
            };
            PushClient.SendPushAsync(PayLoad.ToString());
        }
        #endregion

        #region 推送日历通知
        public static void SendCalendarNotification(string TaskID)
        {
            // 查找通知内容，找到UserID
            NotificationContent content = notifyMgr.GetNotificationContent(TaskID);

            if (content != null)
            {
                // 发送极光推送消息
                Dictionary<string, object> dict = new Dictionary<string, object>();

                dict["type"] = WHConstants.JPush_Workflow_Type;
                dict["title"] = string.Format("日历提醒:{0}", content.Text);
                dict["content"] = new Dictionary<string, object>();
                SendJPushNotification(new List<object>() { content.UserID }, dict);
                // 删除任务
                using (var db = new WhDbContext())
                {
                    var CalendarTask = db.CalendarTask.Where(n => n.TaskID == TaskID).FirstOrDefault();
                    if (CalendarTask != null)
                    {
                        db.CalendarTask.Remove(CalendarTask);
                        db.SaveChanges();
                    }
                }
            }
        }
        #endregion
    }
}